/*
 * Copyright (c) 2006-2021, Halo team
 *
 * SPDX-License-Identifier: GPLv3
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-09-11     Eywen        the first version
 */

#ifndef APPLICATIONS_STEP_H_

#define APPLICATIONS_STEP_H_

#include <rtthread.h>
#include "drivers/drv_smart_step.h"

typedef enum _steper{
    step_x,
    step_y,
    step_z,
    step_xy,
    step_x_left,
    step_x_right,
    step_type_max,
}motion_step_type_t;

typedef struct _step_pulse
{
    float speed;          /* 步进速度 */
    float distace;        /* 步进数量 */
}motion_step_task_t;

typedef enum step_error{
    step_ok = 0,             /* 无错误 */
    step_err_uninit,         /* 未初始化 */
    step_err_stall,          /* 堵转 */
    step_err_unkown,         /* 未知错误 */
}motion_step_err_t;

typedef struct _motion_step motion_step_t;

typedef struct _motion_step_ops{
    bool (*init)(motion_step_t *device, motion_step_type_t type,
                     smart_step_id_t id ,int pin_pwm, int pin_en, int pin_dir,
                     uint32_t timer_freq);
    bool (*add_task)(motion_step_t *step, motion_step_task_t *pulse);
    motion_step_err_t (*error)(motion_step_t *device);
    bool (*start_task)(motion_step_t *step);
    bool (*task_full)(motion_step_t *step);
    bool (*task_empty)(motion_step_t *step);
    void (*axis_range_set)(motion_step_t *step, float axis_length);
    void (*axis_zero_offset_set)(motion_step_t *step, float offset);
    float (*coordinate)(motion_step_t *step);
    void (*forward_level_set)(motion_step_t *step, bool level);
    bool (*is_motion)(motion_step_t *step);
    float (*distance_to_pulse)(motion_step_t *step, float dis);
}motion_step_ops_t;

typedef enum _step_status{
    step_running,
    step_pause,
}motion_step_status_t;

typedef struct _motion_step{
    void *parent;

    motion_step_type_t type;                /* 电机类型 */
    float axis_length;                      /* 坐标轴长度 */
    float home_offset;                      /* 零点偏移 */
    smart_step_t *step_drv;                 /* 底层驱动接口 */
    motion_step_ops_t *ops;                 /* 操作接口 */
    motion_step_err_t err_status;           /* 错误状态 */
    motion_step_status_t running_status;    /* 步进电机运行状态 */
}motion_step_t;

motion_step_ops_t * motion_step_ops_get(motion_step_type_t type);
bool motion_step_register(motion_step_t *device, motion_step_ops_t *ops);

#endif /* APPLICATIONS_STEP_H_ */
